const express = require("express");
const apiRouter = express.Router();
const fs = require("fs");
const writeData = require("../../db/module/writeData");
const readData = require("../../db/module/readData");
const delData = require("../../db/module/delData");
const { getGiteeRepos } = require("../../utils/sync_git");
const { git_res } = require("../../utils/sync_git");
const simpleGit = require("simple-git");
//  引入 SSH 连接和执行命令的公共方法
const { Client } = require("ssh2");
const config = global.config.server;

// 获取所有git列表
apiRouter.post("/getGitList", async (req, res) => {
  // 获取到客户端通过查询字符串发送到服务器的数据
  try {
    let result = await readData(req.body, "git_list");
    res.send(result);
  } catch (error) {
    res.send({
      code: 20000,
      msg: error.message,
    });
  }
});

// 同步git仓库
apiRouter.post("/sync_git", async (req, res) => {
  try {
    let result = await getGiteeRepos();
    res.send(result);
  } catch (error) {
    res.send({
      code: 50000,
      msg: "操作失败" + error.message,
    });
  }
});

// 获取git 提交记录
apiRouter.post("/git_history_message", async (req, res) => {
  try {
    // 构建请求的 URL，使用 Gitee API 获取指定仓库的提交记录
    let { repo_name, branchName } = req.body;
    const url = `https://gitee.com/api/v5/repos/${global.config.gitmanage.giteeUserName}/${repo_name}/commits?sha=${branchName}`;

    // 发送 GET 请求
    const commits = await git_res(url);

    res.send({
      code: 20000,
      data: commits,
      msg: "获取成功",
    });
  } catch (error) {
    // 处理请求过程中可能出现的错误
    res.send({
      code: 50000,
      data: null,
      msg: error,
    });
  }
});

// 获取git分支记录
apiRouter.post("/git_branch_message", async (req, res) => {
  try {
    const url = `https://gitee.com/api/v5/repos/${global.config.gitmanage.giteeUserName}/${req.body.repo_name}/branches`;
    let result = await git_res(url);
    res.send({
      code: 20000,
      data: result,
      msg: "获取成功",
    });
  } catch (error) {
    res.send({
      code: 50000,
      data: null,
      msg: error,
    });
  }
});

// 查询本地仓库与远程仓库之间的差异
apiRouter.post("/checkDiff", async (req, res) => {
  const { localRepoPath, branch = "master" } = req.body;

  // 创建 simple-git 实例，指定本地仓库的基础目录
  const git = simpleGit({ baseDir: localRepoPath });

  try {
    // 获取本地仓库的远程仓库列表
    const remotes = await git.getRemotes(true);

    // 检查本地仓库是否存在名为 "origin" 的远程仓库
    const originExists = remotes.some((remote) => remote.name === "origin");

    // 判断本地仓库是否存在 "origin" 远程仓库
    if (!originExists) {
      res.send({
        code: 50000,
        msg: "本地仓库不存在名为 'origin' 的远程仓库，请先添加远程仓库。",
      });
    }

    // 获取本地和远程分支的差异
    await git.fetch("origin", branch);
    const diff = await git.diff(["origin/" + branch]);

    res.send({
      code: 20000,
      msg: `成功获取 ${branch} 分支的文件差异`,
      data: diff,
    });
  } catch (error) {
    console.error("检查差异过程中出现错误:", error);
    // 检查差异过程中出现其他错误，返回错误信息
    res.send({
      code: 50000,
      msg: `检查 ${branch} 分支文件差异时发生错误：${error.message}`,
    });
  }
});

// 将项目推送到远程
apiRouter.post("/commit", async (req, res) => {
  const {
    localRepoPath,
    html_url,
    username,
    password,
    branch = "master",
    commit_message,
  } = req.body;

  // 处理远程仓库地址，添加账号密码信息
  const authRemoteRepoUrl = html_url.replace(
    "https://",
    `https://${username}:${password}@`
  );

  // 创建 simple-git 实例，指定本地仓库的基础目录
  const git = simpleGit({ baseDir: localRepoPath });

  try {
    // 获取本地仓库的远程仓库列表
    const remotes = await git.getRemotes(true);

    // 检查本地仓库是否存在名为 "origin" 的远程仓库
    const originExists = remotes.some((remote) => remote.name === "origin");

    // 判断本地仓库是否存在 "origin" 远程仓库
    if (!originExists) {
      // 如果 "origin" 远程仓库不存在，则添加
      await git.addRemote("origin", authRemoteRepoUrl);
    } else {
      // 如果 "origin" 已存在，更新远程仓库地址
      // 先移除原有的 "origin" 远程仓库，忽略移除过程中可能出现的错误
      await git.removeRemote("origin").catch(() => { });
      // 再添加新的 "origin" 远程仓库
      await git.addRemote("origin", authRemoteRepoUrl);
    }

    // 拉取远程代码
    try {
      await git.pull("origin", branch);
    } catch (pullError) {
      if (pullError.message.includes("conflict")) {
        // 处理拉取时的冲突错误
        const status = await git.status();
        const conflictFiles = status.conflicted;

        return res.send({
          code: 50000,
          msg: `拉取 ${branch} 分支代码时发生冲突，请手动解决冲突后再尝试提交`,
          conflictFiles,
        });
      } else {
        // 处理其他拉取错误
        return res.send({
          code: 50000,
          msg: `拉取 ${branch} 分支代码时发生错误：${pullError.message}`,
        });
      }
    }

    // 添加所有文件到暂存区
    await git.add("./*");

    // 获取提交前的文件状态
    const preCommitStatus = await git.status();

    // 提交暂存区的文件到本地仓库
    await git.commit(commit_message || "自动提交更新");

    try {
      // 将本地仓库的指定分支推送到远程仓库的对应分支
      await git.push("origin", branch);

      // 获取提交后的文件状态
      const postCommitStatus = await git.status();

      // 找出提交的文件列表
      const committedFiles = postCommitStatus.files
        .filter((file) => {
          return preCommitStatus.files.some(
            (preFile) => preFile.path === file.path
          );
        })
        .map((file) => file.path);

      // 提交成功，返回成功信息和提交的文件列表
      res.send({
        code: 20000,
        msg: `本地项目已成功提交到远程仓库的 ${branch} 分支`,
        committedFiles,
      });
    } catch (pushError) {
      if (pushError.message.includes("conflict")) {
        // 处理推送时的冲突错误
        const status = await git.status();
        const conflictFiles = status.conflicted;

        res.send({
          code: 50000,
          msg: `提交到 ${branch} 分支时发生冲突，请手动解决冲突后再尝试提交`,
          conflictFiles,
        });
      } else {
        // 处理其他推送错误
        res.send({
          code: 50000,
          msg: `提交到 ${branch} 分支时发生错误：${pushError.message}`,
        });
      }
    }
  } catch (error) {
    console.error("提交过程中出现错误:", error);
    // 提交过程中出现其他错误，返回错误信息
    res.send({
      code: 50000,
      msg: `提交到 ${branch} 分支时发生错误：${error.message}`,
    });
  }
});

// 修改仓库列表
apiRouter.post("/gitmanageUpdate", async (req, res) => {
  try {
    let result = await writeData(req.body, "git_list");
    res.send(result);
  } catch (error) {
    res.send({
      code: 50000,
      msg: `修改仓库列表时发生错误：${error.message}`,
    });
  }
});


module.exports = apiRouter;
